#include "EquationSolver.h"
#include <limits>

double pi = acos(-1);
double eps = numeric_limits<double>::epsilon();

class Func : public Function{
private:
  double l, beta1, h, D;
  double A, B, C, E;
public:
  Func(double _l, double _h, double _D, double _beta1){
    l = _l; beta1 = _beta1; h = _h; D = _D;
    A = l*sin(beta1/(360));
    B = l*cos(beta1/(360));
    C = (h+0.5*D)*sin(beta1/(360))-0.5*D*tan(beta1/(360));
    E = (h+0.5*D)*cos(beta1/(360))-0.5*D;
  }
  double operator()(double x){
    return A*sin(x)*cos(x)+B*pow(sin(x),2)-C*cos(x)-E*sin(x);
  }
  double diff(double x){
    return A*cos(2*x)+B*sin(2*x)+C*sin(x)-E*cos(x);
  }
};

Func f(89, 49, 55, 11.5);

double testa(){
  Newton solver(f, pi/2.5, eps, 10);
  double result = solver.solve();
  result = result*180/pi;
  return result;
}

Func fb(89, 49, 40, 11.5);

double testb(){
  Newton solver(fb, pi*33/180, eps, 10);
  double result = solver.solve()*180/pi;
  return result;
}

double testc(){
  Secant solver(f, pi*33/180, pi*60/180, eps, eps, 10);
  double result = solver.solve();
  result = result*180/pi;
  return result;
}

double testd(){
  Secant solver(f, 10000, pi*33/180, eps, eps, 10);
  double result = solver.solve();
  result = result*180/pi;
  return result;
}

int main(){
  cout << "(a)Alpha = " << testa() << endl;
  cout << "(b)Alpha = " << testb() << endl;
  cout << "(c)Alpha = " << testc() << " with pi*33/180, pi*60/180" << endl;
  cout << "(c)Alpha = " << testd() << " with 10000, pi*33/180" << endl;
  return 0;
}
